// unordered_set standard header
#pragma once
#ifndef _UNORDERED_SET_
#define _UNORDERED_SET_
#ifndef RC_INVOKED
#include <xhash>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma push_macro("new")
 #undef new

_STD_BEGIN
		// TEMPLATE CLASS _Uset_traits
template<class _Kty,	// key type (same as value type)
	class _Tr,	// comparator predicate type
	class _Alloc,	// actual allocator type (should be value allocator)
	bool _Mfl>	// true if multiple equivalent keys are permitted
	class _Uset_traits
		: public _Tr
	{	// traits required to make _Hash behave like a set
public:
	typedef _Kty key_type;
	typedef _Kty value_type;
	typedef _Tr key_compare;
	typedef _Alloc allocator_type;

	enum
		{	// make multi parameter visible as an enum constant
		_Multi = _Mfl};

	_Uset_traits(const _Tr& _Traits = _Tr())
		: _Tr(_Traits)
		{	// construct with specified comparator
		}

	typedef key_compare value_compare;

	static const _Kty& _Kfn(const value_type& _Val)
		{	// return entire value as key
		return (_Val);
		}

	static int _Nonkfn(const value_type&)
		{	// extract "non-key" from element value (for container equality)
		return (0);
		}
	};

		// TEMPLATE CLASS unordered_set
template<class _Kty,
	class _Hasher = hash<_Kty>,
	class _Keyeq = equal_to<_Kty>,
	class _Alloc = allocator<_Kty> >
	class unordered_set
		: public _Hash<_Uset_traits<_Kty,
			_Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, false> >
	{	// hash table of key values, unique keys
public:
	typedef unordered_set<_Kty, _Hasher, _Keyeq, _Alloc> _Myt;
	typedef _Uhash_compare<_Kty, _Hasher, _Keyeq> _Mytraits;
	typedef _Hash<_Uset_traits<_Kty,
		_Mytraits, _Alloc, false> > _Mybase;
	typedef _Hasher hasher;
	typedef _Kty key_type;
	typedef _Keyeq key_equal;
	typedef _Mytraits key_compare;	// extra

	typedef typename _Mybase::_Pairib _Pairib;
//	typedef typename _Mybase::value_compare value_compare;
	typedef typename _Mybase::allocator_type allocator_type;
	typedef typename _Mybase::size_type size_type;
	typedef typename _Mybase::difference_type difference_type;
	typedef typename _Mybase::pointer pointer;
	typedef typename _Mybase::const_pointer const_pointer;
	typedef typename _Mybase::reference reference;
	typedef typename _Mybase::const_reference const_reference;
	typedef typename _Mybase::iterator iterator;
	typedef typename _Mybase::const_iterator const_iterator;
//	typedef typename _Mybase::reverse_iterator reverse_iterator;
//	typedef typename _Mybase::const_reverse_iterator
//		const_reverse_iterator;
	typedef typename _Mybase::value_type value_type;

	typedef typename _Mybase::iterator local_iterator;
	typedef typename _Mybase::const_iterator const_local_iterator;

	unordered_set()
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults
		}

	explicit unordered_set(const allocator_type& _Al)
		: _Mybase(key_compare(), _Al)
		{	// construct empty set from defaults, allocator
		}

	unordered_set(const _Myt& _Right)

 #if _HAS_CPP0X
		: _Mybase(_Right,
			_Right._List._Getal().select_on_container_copy_construction())

 #else /* _HAS_CPP0X */
		: _Mybase(_Right, _Right._List._Getal())
 #endif /* _HAS_CPP0X */

		{	// construct set by copying _Right
		}

	unordered_set(const _Myt& _Right, const allocator_type& _Al)
		: _Mybase(_Right, _Al)
		{	// construct set by copying _Right, allocator
		}

	explicit unordered_set(size_type _Buckets)
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults, ignore initial size
		this->rehash(_Buckets);
		}

	unordered_set(size_type _Buckets, const hasher& _Hasharg)
		: _Mybase(key_compare(_Hasharg), allocator_type())
		{	// construct empty set from hasher
		this->rehash(_Buckets);
		}

	unordered_set(size_type _Buckets, const hasher& _Hasharg,
		const _Keyeq& _Keyeqarg)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), allocator_type())
		{	// construct empty set from hasher and equality comparator
		this->rehash(_Buckets);
		}

	unordered_set(size_type _Buckets, const hasher& _Hasharg,
		const _Keyeq& _Keyeqarg, const allocator_type& _Al)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), _Al)
		{	// construct empty set from hasher and equality comparator
		this->rehash(_Buckets);
		}

	template<class _Iter>
		unordered_set(_Iter _First, _Iter _Last)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from sequence, defaults
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_set(_Iter _First, _Iter _Last,
			size_type _Buckets)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from sequence, ignore initial size
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_set(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg)
		: _Mybase(key_compare(_Hasharg), allocator_type())
		{	// construct set from sequence, comparator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_set(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg,
			const _Keyeq& _Keyeqarg)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), allocator_type())
		{	// construct set from sequence, comparator, and allocator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_set(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg,
			const _Keyeq& _Keyeqarg, const allocator_type& _Al)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), _Al)
		{	// construct set from sequence, comparator, and allocator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign by copying _Right
		_Mybase::operator=(_Right);
		return (*this);
		}

	unordered_set(_Myt&& _Right)
		: _Mybase(_STD move(_Right), _Right._List._Getal())
		{	// construct set by moving _Right
		}

	unordered_set(_Myt&& _Right, const allocator_type& _Al)
		: _Mybase(_STD move(_Right), _Al)
		{	// construct set by moving _Right, allocator
		}

	_Myt& operator=(_Myt&& _Right)
		{	// assign by moving _Right
		_Mybase::operator=(_STD move(_Right));
		return (*this);
		}

	_Pairib insert(value_type&& _Val)
		{	// insert a {key, mapped} value
		return (_Mybase::insert(_STD forward<value_type>(_Val)));
		}

	iterator insert(const_iterator _Where, value_type&& _Val)
		{	// insert a {key, mapped} value, with hint
		return (_Mybase::insert(_Where, _STD forward<value_type>(_Val)));
		}

	void swap(_Myt& _Right)
		{	// exchange contents with non-movable _Right
		_Mybase::swap(_Right);
		}

	hasher hash_function() const
		{	// return hasher object
		return (this->_Gethash());
		}

	key_equal key_eq() const
		{	// return equality comparator object
		return (this->_Getkeyeq());
		}

	_Pairib insert(const value_type& _Val)
		{	// insert a key value
		return (_Mybase::insert(_Val));
		}

	iterator insert(const_iterator _Where, const value_type& _Val)
		{	// insert a key value, with hint
		return (_Mybase::insert(_Where, _Val));
		}

	template<class _Iter>
		void insert(_Iter _First, _Iter _Last)
		{	// insert [_First, _Last), arbitrary iterators
		_Mybase::insert(_First, _Last);
		}
	};

template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc>
	void swap(unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// swap _Left and _Right unordered_sets
	_Left.swap(_Right);
	}

 #if _HAS_CPP0X
template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc> inline
	bool operator==(
		const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// test for unordered_set equality
	return (_Hash_equal(_Left, _Right));
	}

template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc> inline
	bool operator!=(
		const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// test for unordered_set inequality
	return (!(_Left == _Right));
	}
 #endif /* _HAS_CPP0X */

		// TEMPLATE CLASS unordered_multiset
template<class _Kty,
	class _Hasher = hash<_Kty>,
	class _Keyeq = equal_to<_Kty>,
	class _Alloc = allocator<_Kty> >
	class unordered_multiset
		: public _Hash<_Uset_traits<_Kty,
			_Uhash_compare<_Kty, _Hasher, _Keyeq>, _Alloc, true> >
	{	// hash table of key values, non-unique keys
public:
	typedef unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc> _Myt;
	typedef _Uhash_compare<_Kty, _Hasher, _Keyeq> _Mytraits;
	typedef _Hash<_Uset_traits<_Kty,
		_Mytraits, _Alloc, true> > _Mybase;
	typedef _Hasher hasher;
	typedef _Kty key_type;
	typedef _Keyeq key_equal;
	typedef _Mytraits key_compare;	// extra

//	typedef typename _Mybase::value_compare value_compare;
	typedef typename _Mybase::allocator_type allocator_type;
	typedef typename _Mybase::size_type size_type;
	typedef typename _Mybase::difference_type difference_type;
	typedef typename _Mybase::pointer pointer;
	typedef typename _Mybase::const_pointer const_pointer;
	typedef typename _Mybase::reference reference;
	typedef typename _Mybase::const_reference const_reference;
	typedef typename _Mybase::iterator iterator;
	typedef typename _Mybase::const_iterator const_iterator;
//	typedef typename _Mybase::reverse_iterator reverse_iterator;
//	typedef typename _Mybase::const_reverse_iterator
//		const_reverse_iterator;
	typedef typename _Mybase::value_type value_type;

	unordered_multiset()
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults
		}

	explicit unordered_multiset(const allocator_type& _Al)
		: _Mybase(key_compare(), _Al)
		{	// construct empty set from defaults, allocator
		}

	unordered_multiset(const _Myt& _Right)

 #if _HAS_CPP0X
		: _Mybase(_Right,
			_Right._List._Getal().select_on_container_copy_construction())

 #else /* _HAS_CPP0X */
		: _Mybase(_Right, _Right._List._Getal())
 #endif /* _HAS_CPP0X */

		{	// construct set by copying _Right
		}

	unordered_multiset(const _Myt& _Right, const allocator_type& _Al)
		: _Mybase(_Right, _Al)
		{	// construct set by copying _Right, allocator
		}

	explicit unordered_multiset(size_type _Buckets)
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults, ignore initial size
		this->rehash(_Buckets);
		}

	unordered_multiset(size_type _Buckets, const hasher& _Hasharg)
		: _Mybase(key_compare(_Hasharg), allocator_type())
		{	// construct empty set from hasher
		this->rehash(_Buckets);
		}

	unordered_multiset(size_type _Buckets, const hasher& _Hasharg,
		const _Keyeq& _Keyeqarg)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), allocator_type())
		{	// construct empty set from hasher and equality comparator
		this->rehash(_Buckets);
		}

	unordered_multiset(size_type _Buckets, const hasher& _Hasharg,
		const _Keyeq& _Keyeqarg, const allocator_type& _Al)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), _Al)
		{	// construct empty set from hasher and equality comparator
		this->rehash(_Buckets);
		}

	template<class _Iter>
		unordered_multiset(_Iter _First, _Iter _Last)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from sequence, defaults
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_multiset(_Iter _First, _Iter _Last,
			size_type _Buckets)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from sequence, defaults, ignore initial size
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_multiset(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg)
		: _Mybase(key_compare(_Hasharg), allocator_type())
		{	// construct set from sequence, comparator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_multiset(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg,
			const _Keyeq& _Keyeqarg)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), allocator_type())
		{	// construct set from sequence, comparator, and allocator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	template<class _Iter>
		unordered_multiset(_Iter _First, _Iter _Last,
			size_type _Buckets, const hasher& _Hasharg,
			const _Keyeq& _Keyeqarg, const allocator_type& _Al)
		: _Mybase(key_compare(_Hasharg, _Keyeqarg), _Al)
		{	// construct set from sequence, comparator, and allocator
		this->rehash(_Buckets);
		_Mybase::insert(_First, _Last);
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign by copying _Right
		_Mybase::operator=(_Right);
		return (*this);
		}

	unordered_multiset(_Myt&& _Right)
		: _Mybase(_STD move(_Right), _Right._List._Getal())
		{	// construct set by moving _Right
		}

	unordered_multiset(_Myt&& _Right, const allocator_type& _Al)
		: _Mybase(_STD move(_Right), _Al)
		{	// construct set by moving _Right, allocator
		}

	_Myt& operator=(_Myt&& _Right)
		{	// assign by moving _Right
		_Mybase::operator=(_STD move(_Right));
		return (*this);
		}

	iterator insert(value_type&& _Val)
		{	// insert a {key, mapped} value
		return (_Mybase::insert(_STD forward<value_type>(_Val)).first);
		}

	iterator insert(const_iterator _Where, value_type&& _Val)
		{	// insert a {key, mapped} value, with hint
		return (_Mybase::insert(_Where, _STD forward<value_type>(_Val)));
		}

#define _UNORDERED_MULTISET_EMPLACE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
	TEMPLATE_LIST(_CLASS_TYPE) \
		iterator emplace(LIST(_TYPE_REFREF_ARG)) \
		{	/* try to insert value_type(_Val...), favoring right side */ \
		return (_Mybase::emplace(LIST(_FORWARD_ARG)).first); \
		}

_VARIADIC_EXPAND_0X(_UNORDERED_MULTISET_EMPLACE, , , , )
#undef _UNORDERED_MULTISET_EMPLACE

	void swap(_Myt& _Right)
		{	// exchange contents with non-movable _Right
		_Mybase::swap(_Right);
		}

	hasher hash_function() const
		{	// return hasher object
		return (this->_Gethash());
		}

	key_equal key_eq() const
		{	// return equality comparator object
		return (this->_Getkeyeq());
		}

	iterator insert(const value_type& _Val)
		{	// insert a key value
		return (_Mybase::insert(_Val).first);
		}

	iterator insert(const_iterator _Where, const value_type& _Val)
		{	// insert a key value, with hint
		return (_Mybase::insert(_Where, _Val));
		}

	template<class _Iter>
		void insert(_Iter _First, _Iter _Last)
		{	// insert [_First, _Last), arbitrary iterators
		_Mybase::insert(_First, _Last);
		}
	};

template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc>
	void swap(unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// swap _Left and _Right unordered_multisets
	_Left.swap(_Right);
	}

 #if _HAS_CPP0X
template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc> inline
	bool operator==(
		const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// test for unordered_multiset equality
	return (_Hash_equal(_Left, _Right));
	}

template<class _Kty,
	class _Hasher,
	class _Keyeq,
	class _Alloc> inline
	bool operator!=(
		const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
		const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Right)
	{	// test for unordered_multiset inequality
	return (!(_Left == _Right));
	}
 #endif /* _HAS_CPP0X */

namespace tr1 {	// TR1 ADDITIONS
using _STD unordered_multiset;
using _STD unordered_set;
}	// namespace tr1
_STD_END
 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _UNORDERED_SET_ */

/*
 * Copyright (c) 1992-2012 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V6.00:0009 */
